
package ufs.cmds;

import ufs.file.UfsStream;
import joptsimple.OptionException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;

public class ufs_mke2fs {

	private static short clusterDim = UFSCommandsConstants.DEFAULT_DIM_CLUSTER;
	private static int clusterNum = UFSCommandsConstants.DEFAULT_NUM_CLUSTER;
	private static String nameVol = UFSCommandsConstants.DEFAULT_NAME_VOL;

	public static void main(String[] args) {

		OptionParser parser = new OptionParser();

        parser.accepts( "c" ).withRequiredArg().ofType( Short.class );
        parser.accepts( "k" ).withRequiredArg().ofType( Integer.class );
        parser.accepts( "n" ).withRequiredArg().ofType( String.class );


        OptionSet options = parser.parse( );


        Short cOpt = null;
        Integer kOpt = null;
        
        /* Checking -c option*/
        try {
        	cOpt = (Short) options.valueOf("c");
        	
        } catch (OptionException  e) {
        	 System.out.println(String.format( UFSCommandsConstants.WRONG_C_ARG ,UFSCommandsConstants.ClusterDims.printSet() ,"c") );
        }

        if(cOpt != null) {
           	if(UFSCommandsConstants.ClusterDims.contains(cOpt)) {
           		clusterDim = cOpt;
            } else {
            	System.out.println(String.format( UFSCommandsConstants.WRONG_C_ARG , "c") );
            }
        }

        /* Checking -k option*/
        try {
        	kOpt = (Integer) options.valueOf("k");
        	
        } catch (OptionException  e) {
        	 System.out.println(String.format( UFSCommandsConstants.WRONG_K_ARG ,UFSCommandsConstants.ClusterDims.printSet() ,"k") );
        }
        
        if(kOpt != null) {
        	clusterNum = kOpt;
        }
        
		int fatSize = (1 + clusterNum) * UFSCommandsConstants.FAT_ITEM_SIZE;
		
        String nameVolArg = (String)options.valueOf("n");
        if(nameVolArg!=null && checkNameVol(nameVolArg)) {
        	
    		nameVol = nameVolArg;
    		makeBootSector(UFSCommandsConstants.nameFile,fatSize);
        }

        if(nameVolArg == null) {
    		makeBootSector(UFSCommandsConstants.nameFile,fatSize);
        }
        
        
	}

	private static boolean checkNameVol(String nameVolArg) {
		if(nameVolArg.length()>10) {
			System.out.println(String.format( UFSCommandsConstants.WRONG_N_ARG , "n") );
			return false;
		}
			
		return true;
	}

	private static void makeBootSector(String fileName,int fatSize) {
		UfsStream writer = new UfsStream(fileName);
		
		boolean exists = writer.exists();
		if(exists == true) {
			System.out.println( UFSCommandsConstants.FS_ALREADY_EXISTS );
			return;
		}
		
		boolean ret = writer.CreateFS();
		if(ret == false) {
			return;
		}
		
		// write Boot Sector
		writer.wShort(clusterDim);
		writer.wInt(clusterNum);
		

		writer.wInt(fatSize);
		
		writer.wByte(UFSCommandsConstants.MINOR_VERSION);
		writer.wByte(UFSCommandsConstants.MAJOR_VERSION);
		
		writer.wInt(UFSCommandsConstants.FIRST_CLUSTER_INDEX);
		writer.wInt(0);

		writer.wString(nameVol,UFSCommandsConstants.DEFAULT_NAME_VOL_SIZE);
		
		writer.wByte((byte)UFSCommandsConstants.FIRST_CODE_TYPE);
		writer.wByte(UFSCommandsConstants.SECOND_CODE_TYPE);
		
		// initialize FAT
		for(int i=0; i<fatSize; i++) {
			writer.wInt(0);
		}

		// delimit data area
		int fileSize = UFSCommandsConstants.BOOT_SECTOR_SIZE + fatSize + clusterDim*(clusterNum);
		writer.seek(fileSize-1);
		byte b = 0;
		writer.wByte(b);
		
		writer.close();
	}

}
